using Wilco.SyntaxHighlighting.Engine.Highlighter;
using Wilco.SyntaxHighlighting.Engine.Highlighter.Implementation;
using Wilco.SyntaxHighlighting.Engine.Scanner;
using Wilco.SyntaxHighlighting.Engine.Scanner.Implementation;
using Wilco.SyntaxHighlighting.Engine.Scanner.Implementation.ASPX;
using Wilco.SyntaxHighlighting.Engine.Scanner.Implementation.PHP;
using Wilco.SyntaxHighlighting.Engine.Tokenizer;

namespace Wilco.SyntaxHighlighting.Engine
{
    /// <summary>
    /// Represents a register.
    /// </summary>
    public class Register
    {
        /// <summary>
        /// Gets an instance of the register as a singleton.
        /// </summary>
        public static readonly Register Instance = new Register();

        private readonly HighlighterCollection highlighters;
        private readonly ScannerCollection scanners;

        /// <summary>
        /// Gets the registered highlighters.
        /// </summary>
        public HighlighterCollection Highlighters
        {
            get
            {
                return highlighters;
            }
        }

        /// <summary>
        /// Gets the registered scanners.
        /// </summary>
        public ScannerCollection Scanners
        {
            get
            {
                return scanners;
            }
        }

        /// <summary>
        /// Initializes a new instance of a <see cref="Register"/> class.
        /// </summary>
        static Register()
        {
            //
        }

        /// <summary>
        /// Initializes a new instance of a <see cref="Register"/> class.
        /// </summary>
        private Register()
        {
            highlighters = new HighlighterCollection();
            scanners = new ScannerCollection();
            InitializeHighlighters();
            InitializeScanners(new CharTokenizer());
        }

        /// <summary>
        /// Registers the highlighters.
        /// </summary>
        private void InitializeHighlighters()
        {
            AddHighlighter(new ASPXHighlighter());
            AddHighlighter(new XMLHighlighter());
            AddHighlighter(new CHighlighter());
            AddHighlighter(new CobolHighlighter());
            AddHighlighter(new ColdFusionHighlighter());
            AddHighlighter(new CPPHighlighter());
            AddHighlighter(new CSSHighlighter());
            AddHighlighter(new CSharpHighlighter());
            AddHighlighter(new EiffelHighlighter());
            AddHighlighter(new FortranHighlighter());
            AddHighlighter(new HaskellHighlighter());
            AddHighlighter(new JavaHighlighter());
            AddHighlighter(new JavaScriptHighlighter());
            AddHighlighter(new JScriptHighlighter());
            AddHighlighter(new MercuryHighlighter());
            AddHighlighter(new MSILHighlighter());
            AddHighlighter(new PascalHighlighter());
            AddHighlighter(new PerlHighlighter());
            AddHighlighter(new PHPHighlighter());
            AddHighlighter(new PythonHighlighter());
            AddHighlighter(new RubyHighlighter());
            AddHighlighter(new SQLHighlighter());
            AddHighlighter(new VBHighlighter());
            AddHighlighter(new VBSHighlighter());
        }

        /// <summary>
        /// Registers the scanners.
        /// </summary>
        private void InitializeScanners(TokenizerBase tokenizer)
        {
            scanners.Add(new CommentBlockScanner());
            scanners.Add(new CommentLineScanner());
            scanners.Add(new StringBlockScanner());
            scanners.Add(new StringLineScanner());
            scanners.Add(new WordScanner());
            scanners.Add(new XmlScanner());
            scanners.Add(new ASPXScanner());
            scanners.Add(new PHPScanner());
        }

        /// <summary>
        /// Adds a highlighter to the register.
        /// </summary>
        /// <param name="highlighter">The highlighter to add.</param>
        private void AddHighlighter(HighlighterBase highlighter)
        {
            highlighters.Add(highlighter);
        }
    }
}